<?php

include dirname(__FILE__)."/adodb/adodb.inc.php";

/*
    Common core class.
    This class provide generic access to databases
*/

class CoreDB
{

    var $db;
    var $db_cache;
    
    /**
     * CoreDB class constructor
     *
     * @param string $driver
     *          Example:
     *                   "mysql://<db_user>:<db_pass>@<db_server>/<db_database>"
     */

      function initCache($cacheon_off){
    include dirname(__FILE__).'/coredb.caching.php';
    $db_cache = new sqlQueryCache();
    $db_cache->init();
    $db_cache->enabled = $cacheon_off;

    $this->db_cache = $db_cache;
    } 

      function showCache(){
        $this->db_cache->showCache();
    }

    function str2db($str)
    {
        return addslashes(trim($str));
    }


    function db2str($str)
    {
        return stripslashes($str);
    }


function ArrayStr2db(&$arr, $deep = 0 )
{
    if(is_array($arr) && count($arr))
    {
        foreach($arr as $k => $v)
        {
            if(is_array($v) && count($v))
            {
                $this->ArrayStr2db($v, $deep+1);
            }
            if(is_string($v))
            {
                $arr[$k] = $this->str2db($v);
            }
            else
            {
                $arr[$k] = $v;
            }
        } // end foreach
    }
    return $arr;
}

function ArrayDb2Str(&$arr, $deep = 0 )
{
    if(is_array($arr) && count($arr))
    {
        foreach($arr as $k => $v)
        {
            if(is_array($v) && count($v))
            {
                ArrayDb2Str($v, $deep+1);
            }
            if(is_string($v))
            {
                $arr[$k] = db2str($v);
            }
            else
            {
                $arr[$k] = $v;
            }
        } // end foreach
    }
    return $arr;
}

    function CoreDB($driver)
    {
        $this->db = &ADONewConnection($driver);
    }


    /**
     * Check if there was DB error and if so than die with displaying SQL error
     *
     */

    function ErrorDie($sql)
    {
        if($this->db->ErrorNo())
        {
        
            $dberrmsg = $this->db->ErrorMsg();
            $errmsg = ereg_replace("[^a-zA-Z_0-9,() ]",'',$sql);
            $dberrmsg = ereg_replace("[^a-zA-Z_0-9,() ]",'',$dberrmsg);
            
            echo'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">'."\r\n";
            echo '<html>';
            echo '<head><title>Error</title></head>';
            echo '<body bgcolor="#bebebe">';
            echo '<center>';
            $newmsg2 = "<br /><u>Something might have happened</u>.
                        <br /></pre><h1 style='color:red;'>$dberrmsg</h1><br />
                        <img src='/admin/img/db_offline.gif' border='0' alt='Try again.' onclick='javascript: window.history.go(-1);'><br />
                        <br /> <div style='border:1px solid;'>$sql</div>";

        echo "<div><pre style=\"border:1px solid #000000; background-color: #CDCDCD;\">".("" == $comments ? "" : "<b>$comments</b>\n");
        print_r($newmsg2);
        echo "\n</div></center>\n\n";
        
        echo '</body>';
        echo '</html>';
        $this->db->Disconnect();
                
        die();
        }
    }

    function ErrorDieOld($sql = null)
    {
        if($this->db->ErrorNo())
        {
            die("SQL error: ".$this->db->ErrorMsg().("" != $sql ? "\n<hr />\n{$sql}" : ""));
        }
    }


    /**
     * getOne returns one value result from SQL command execution
     *
     * @param string $sql
     * @return mixed value
     */
    function getOne($sql)
    {
        $r = $this->db_cache->getFromCache($sql,'one');
        if($r == false){
            $r = $this->db->getOne($sql);
            $this->ErrorDie($sql);
            $this->db_cache->addToCache($sql,$r);
                    $this->db_cache->doLog($sql);
            return $this->db2str($r);
        }

        return $this->db2str($r);
    }


    /**
     * getRow return DB row as named, indexed or both type array
     *
     * @param string  $sql - SQL command to execute
     * @param integet $mode 0 - Show named columns (default);
                            1 - Show indexes columns
                            2 - Show indexes & named columns
     * @return result array
     */
    function getRow($sql, $mode = 0)
    {
        $r = $this->db_cache->getFromCache($sql,'row');
            if($r == false){
            $this->db->SetFetchMode(0 == $mode ? ADODB_FETCH_ASSOC : (1 == $mode ? ADODB_FETCH_NUM : ADODB_FETCH_BOTH));
            $r = $this->db->getRow($sql);
            $this->ErrorDie($sql);
            $this->db_cache->addToCache($sql,$r);
                    $this->db_cache->doLog($sql);
            return $this->arraydb2str($r);
        }
        
        return $this->arraydb2str($r);
    }
    
    /**
     * Return two dimentional array of the result from the sql command
     *
     * @param string  $sql - SQL command to execute
     * @param integet $mode 0 - Show named columns (default);
                            1 - Show indexes columns
                            2 - Show indexes & named columns
     * @param array $arr - array values (?, ?)
     * @param integer $numrows - return $numrows records
     * @param integer $offset - start from $offset record

     * @return two dimentional result array 
     */

    function getAll($sql, $mode = 0, $arr = false, $numrows=-1, $offset=-1)
    {
        
        $this->db->SetFetchMode(0 == $mode ? ADODB_FETCH_ASSOC : (1 == $mode ? ADODB_FETCH_NUM : ADODB_FETCH_BOTH));

        $r = $this->db_cache->getFromCache($sql,'all');
    
        if($r == false){
    
        
//      debug(array($sql, $mode, $arr, $numrows, $offset), "getAll");
        if(-1 == $numrows  &&  -1 == $offset)
        {
            $r = @$this->db->getAll($sql);

        }
        else
        {
            $w = $this->db->SelectLimit($sql, $numrows, $offset, $arr);
            $this->ErrorDie($sql);
            $r = array();
            while($arr = $w->FetchRow())
            {
                $r[] = $this->arraydb2str($arr);
            }
        }

        #$this->ErrorDie('<u>'.__CLASS__.'</u> at <b>'.__FUNCTION__."</b> is dead. <b>$sql</b> <br> go <a style='color:red;' href='javascript: window.history.go(-1);'>i'll be back</a> ");
        $this->ErrorDie('<b>'.__FUNCTION__.'</b> '.$sql);

        $this->db_cache->addToCache($sql,$r);
                $this->db_cache->doLog($sql);
        return ($this->ArrayDb2Str($r));


         }
         else{
            return $this->ArrayDb2Str($r);
        }
        
    }


    /**
     * Return last inserted ID
     *
     * @return last record ID
     */
    function getInsertID()
    {
        return $this->db->Insert_ID();
    }


    /**
     * Function do common SQL request. Available commands are INSERT/DELETE/UPDATE/SELECT
     *
     * @param string $sql
     * @param integer $mode
     * @param array $prm
     * @return return 0 if it was UPDATE/DELETE
               return ID of last inserted record if there was INSERT command executed
               return result array if SELECT command was given
     */
    function Exec($sql, $mode = 0, $prm = null)
    {
        $w = split(" ", $sql);
        $fl = 0;
        $result = "";
        if("insert" == trim(strtolower($w[0])))
        {
            $fl = 1;
        } else 
        if("select" == trim(strtolower($w[0])))
        {
            $fl = 2;
        }

        
        $this->db->SetFetchMode(0 == $mode ? ADODB_FETCH_ASSOC : (1 == $mode ? ADODB_FETCH_NUM : ADODB_FETCH_BOTH));

        if(null != $prm)
        {
            $csql = $this->db->Prepare($sql);
            $result = array();
            foreach ($prm as $p)
            {
                if(2 == $fl)
                {
                    $res = $this->db->Execute($csql, $p);
                    $result[] = $res->FetchRow();
                }
                else
                {
                    $result[] = $this->db->Execute($csql, $p);
                }
            }
            return $result;
        }
        else
        {
            $result = $this->db->Execute($sql);
        }
        $this->ErrorDie($sql);
        
        // -- Check if there was SELECT command
        if("select" == trim(strtolower($w[0])))
        {
            echo "<b>".$result->RecordCount()."</B>";
            $res = array();
            while($arr = $result->FetchRow())
            {
                $res[] = $arr;
                $result->MoveNext();
            }
            $result = $res;
        }
        else
            $result = 0;

        return (1 == $fl) ? $this->getInsertID() : $result;
    }

};


?>